#!/bin/env python2.7
#coding:utf-8

import pymongo
import traceback
import sys
import time

def getMgClient():
    client = pymongo.MongoClient("mongo30003i.hebe.grid.sina.com.cn:30003",socketTimeoutMS=11400,connectTimeoutMS=11500,readPreference='secondaryPreferred')
    return client

def getdb(dbname, client = None):
    if not client:
        client = getMgClient()
    db = client.get_database(dbname)
    db.authenticate('sina_cre','sina_cre_simba_123')
    return db

class MongoHandlerOnline:
    def __init__(self):
        clist = list(range(10))+['a','b','c','d','e','f']
        self.featureTableNames = []
        self.contentTableNames = []
        for i in clist:
            for j in clist:
                self.featureTableNames.append('features_%s%s'%(i,j))
                self.contentTableNames.append('raw_%s%s'%(i,j))
        self.docs_col = None
        self.db = None
        self.contentDb = None
        self.client = None
    def _getClient(self):
        if not self.client:
            self.client = getMgClient()

    def _clearDb(self):
        for tname in self.contentTableNames:
            #print(tname
            self.contentDb.get_collection(tname).remove({})
    def getCollention(self,uuid):
        '''
        根据uuid的后两位生成数据表的名称
        '''
        cname = 'features_%s'%uuid[-2:]
        if not self.db:
            self.db = getdb('simba',self._getClient()) 
        return self.db.get_collection(cname)
    def updateFeature(self,data):
        '''
        完整更新，若不存在则只是插入，否则替换数据表中的已有记录
        '''
        try:
            data['_id']=data['uuid']
            self.getCollention(data['uuid']).update_one({'_id':data['_id']},data,upsert=True)
            return ''
        except:
            return traceback.format_exc()

    def partUpdateFeature(self,data):
        '''
        若没有记录，则插入；否则只更新feature中的字段
        '''
        try:
            data['_id']=data['uuid']
            self.getCollention(data['uuid']).update_one({'_id':data['_id']},{'$set':data},upsert=True)
            return ''
        except:
            return traceback.format_exc()

    def removeFeature(self,id,resFlag=False):
        '''
        从features表中删除,移除到features_delete表中
        resFlag如果为True，则返回被移除的信息
        '''
        try:
            #res = self.findFeature(id)
            self.getCollention(id).remove({'_id':id})
            #if res:
            #    if '_id' in res: res.pop('_id')
            #    self.db.features_del.update_one({'_id':id},{"$set":res},upsert=True)
            #return res if resFlag else ''
            return ''
        except:
            return traceback.format_exc()

    def getDocCollention(self):
        if not self.docs_col:
            self.docs_col = getdb('features',self._getClient()).docs
        return self.docs_col

    def updateDocs(self,data):
        '''
        完整更新，若不存在则只是插入，否则替换数据表中的已有记录
        '''
        try:
            data['_id']=data['dataid']
            #data['del_time'] = 0
            self.getDocCollention().find_one_and_replace({'_id':data['_id']},data,upsert=True)
            return ''
        except:
            return traceback.format_exc()

    def partUpdateDocs(self,data):
        '''
        若没有记录，则插入；否则只更新feature中的字段
        '''
        try:
            data['_id']=data['dataid']
            self.getDocCollention().update_one({'_id':data['_id']},{'$set':data},upsert=True)
            return ''
        except:
            return traceback.format_exc()

    def removeDocs(self,dataid,pushtime = None):
        '''
        不从features表中删除，只是增加删除标记
        resFlag如果为True，则返回被移除的信息
        '''
        try:
            if pushtime == None:
                pushtime = int(time.time())
            self.getDocCollention().update_one({'_id':dataid},{'$set':{'del_time':pushtime}},upsert=True)
            return ''
        except:
            return traceback.format_exc()
    def removeDocsByUUID(self,uuid,pushtime=None):
        try:
            col = self.getDocCollention()
            res = col.find_one({"uuid":uuid})
            if not res: return False
            if pushtime == None:
                pushtime = int(time.time())
            col.update_one({"_id":res["_id"]},{'$set':{'del_time':pushtime}})
            return ''
        except:
            return traceback.format_exc()

    def removeDocsActually(self,id,resFlag=False):
        return self.getDocCollention().remove({'_id':id})

    def findDocs(self,dataid):
        return self.getDocCollention().find_one({'_id':dataid})

    def findDocsByUUID(self,uuid):
        return self.getDocCollention().find_one({'uuid':uuid})

    def findFeature(self,uuid):
        if isinstance(uuid,list):#批量请求
            res = []
            for i in uuid:
                res.append(self.getCollention(i).find_one({'_id':i}))#find({'_id':{'$in':uuid}})
            return res
        else:
            return self.getCollention(uuid).find_one({'_id':uuid})

    def getFetureTableNames(self):
        '''
        返回所有fetures表名
        '''
        return self.featureTableNames

    ###########################for temp use####################
    def getContentCollection(self,uuid):
        cname = 'raw_%s'%uuid[-2:]
        if not self.contentDb:
            self.contentDb = getdb('simba_raw',self._getClient()) 
        return self.contentDb.get_collection(cname)
    def findContent(self,uuid):
        return self.getContentCollection(uuid).find_one({'_id':uuid})
    def updateContent(self,data):
        try:
            uuid = data['uuid'].strip('"')
            data['_id']=uuid
            self.getContentCollection(uuid).update_one({'_id':data['_id']},data,upsert=True)
            del data['_id']
            return ''
        except:
            return traceback.format_exc()
    def removeContent(self,id):
        try:
            self.getContentCollection(id).remove({'_id':id})
            return ''
        except:
            return traceback.format_exc()

    def partUpdateContent(self,data,id=None):
        '''
        若没有记录，则插入；否则只更新feature中的字段
        '''
        try:
            if not id:
                id = data['uuid']
            data['_id']=id
            self.getContentCollection(id).update({'_id':id},{'$set':data},upsert=True)
            return ''
        except:
            return traceback.format_exc()

    def addError(self,tableName,data):
        t = getattr(self.db,tableName)
        if not t:
            return False
        t.insert(data)


if __name__=='__main__':
    from datetime import datetime
    import json
    mh = MongoHandlerOnline()

    if len(sys.argv) < 3:
        print("input error! [uuid d2931c44f0b831408c6159a05b4e6ef1] or [dataid comos:ivhuipn4129855]")
        exit()

    field = sys.argv[1]
    _id = sys.argv[2]
    print("fields:{} - _id:{}".format(field, _id))

    if field == "uuid":
        res = mh.findFeature(_id)
        print(res)
    elif field == "dataid":
        ret = mh.findDocs(dataid=_id)
        print(ret)
    else:
        print("field error! ")
